﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using System.Web.Http.Results;
using WPS.Code.Utils;
using WPS.Log;
using WPS.Model;

namespace WPS.Web.Controllers
{
    public class WPSFileController : ApiController
    {
        #region 获取文件元数据
        /// <summary>
        /// 获取文件元数据
        /// </summary>
        /// <returns></returns>
        [HttpGet, Route("v1/3rd/file/info")]
        public JsonResult<JObject> WPSFileInfo()
        {
            LogHelper.Info("进入v1/3rd/file/info");
            try
            {
                string filename = string.Empty;
                string fileId = string.Empty;
                string permission = "read";
                string token = string.Empty;
                string userid = string.Empty;
                WPSFileInfo fileModel = null;
                HttpContextBase httpContextBase = (HttpContextBase)Request.Properties["MS_HttpContext"];
                if (httpContextBase == null)
                {
                    return null;
                }
                HttpRequestBase request = httpContextBase.Request;
                if (request["_w_permission"] != null)
                {
                    permission = request["_w_permission"].ToString();
                }
                if (request[ApiUtils.Token] != null)
                {
                    token = request[ApiUtils.Token].ToString();
                    LogHelper.Info("token：" + token);
                }
                if (request["_w_fid"] != null)
                {
                    fileId = request["_w_fid"].ToString();
                    LogHelper.Info("fileId：" + fileId);
                }
                if (request["_w_userid"] != null)
                {
                    userid = request["_w_userid"].ToString();
                    LogHelper.Info("userid：" + userid);
                }
                if (request.Headers["x-weboffice-file-id"] != null)
                {
                    fileId = request.Headers["x-weboffice-file-id"].ToString();
                    LogHelper.Info("x-weboffice-file-id：" + fileId);
                }
                if (request.Headers["x-wps-weboffice-token"] != null)
                {
                    token = request.Headers["x-wps-weboffice-token"].ToString();
                    LogHelper.Info("x-wps-weboffice-token：" + token);
                }
                if (fileId != null)
                {
                    using (WPSModel context = new WPSModel())
                    {
                        fileModel = context.WPSFileInfo.Where(f => f.ID == fileId).FirstOrDefault();
                    }
                }
                if (fileModel == null)
                {
                    return null;
                }
                LogHelper.Info(" fileModel is not null ");
                filename = fileModel.NAME;
                LogHelper.Info("x-weboffice-file-id：" + fileId + ";<br/>filename：" + filename + ";<br/>_w_permission：" + permission + ";<br/>x-wps-weboffice-token=" + token);
                JObject jsonObject = new JObject();
                JObject fileObj = new JObject();
                JObject userObj = new JObject();
                JObject user_acl = new JObject();
                try
                {
                    DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
                    fileObj.Add("id", fileModel.ID);
                    fileObj.Add("name", fileModel.NAME);
                    fileObj.Add("version", fileModel.VERSION);
                    fileObj.Add("size", fileModel.SIZE);
                    fileObj.Add("creator", fileModel.CREATOR);
                    if (fileModel.CREATE_DATE != null)
                    {
                        long createTimeStamp = (long)(Convert.ToDateTime(fileModel.CREATE_DATE) - startTime).TotalMilliseconds / 1000;
                        fileObj.Add("create_time", createTimeStamp);
                    }
                    fileObj.Add("modifier", fileModel.EDITOR);
                    if (fileModel.EDIT_DATE != null)
                    {
                        long editTimeStamp = (long)(Convert.ToDateTime(fileModel.EDIT_DATE) - startTime).TotalMilliseconds / 1000; ;
                        fileObj.Add("modify_time", editTimeStamp);
                    }
                    fileObj.Add("download_url", fileModel.DOWNLOAD_URL);
                    LogHelper.Info("download_url：" + fileObj["download_url"].ToString());
                    user_acl["rename"] = 1;
                    user_acl["history"] = 1;
                    fileObj.Add("user_acl", user_acl);
                    jsonObject.Add("file", fileObj);
                    LogHelper.Info(" userModel token：" + token);
                    WPSUserInfo userModel = LoginUtils.GetUserInfo(token);
                    if (userModel == null && !string.IsNullOrEmpty(userid))
                    {
                        using (WPSModel context = new WPSModel())
                        {
                            userModel = context.WPSUserInfo.Where(u => u.ID == userid).FirstOrDefault();
                        }
                    }
                    if (userModel == null)
                    {
                        LogHelper.Info(" userModel is   null ");
                    }
                    LogHelper.Info(" userModel is not null ");
                    userObj.Add("id", userModel.ID);
                    userObj.Add("name", userModel.NAME);
                    userObj.Add("permission", permission);
                    userObj.Add("avatar_url", userModel.AVATAR_URL);
                    jsonObject.Add("user", userObj);
                    LogHelper.Info("jsonObject：" + jsonObject.ToString());
                }
                catch (Exception e)
                {
                    LogHelper.Error(e.Message);
                }
                LogHelper.Info("离开v1/3rd/file/info");
                return Json(jsonObject);
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex.Message);
            }
            return null;
        }
        #endregion

        #region 新建文件
        /// <summary>
        /// 新建文件
        /// </summary>
        /// <returns></returns>
        [HttpPost, Route("v1/3rd/file/new")]
        public JsonResult<JObject> NewFile()
        {
            try
            {
                LogHelper.Info("进入v1/3rd/file/new");
                string fileId = string.Empty;
                string token = string.Empty;
                string userId = string.Empty;
                JObject obj = new JObject();
                HttpContextBase httpContextBase = (HttpContextBase)Request.Properties["MS_HttpContext"];
                if (httpContextBase == null)
                {
                    return null;
                }
                HttpRequestBase request = httpContextBase.Request;
                if (request.Headers["x-weboffice-file-id"] != null)
                {
                    fileId = request.Headers["x-weboffice-file-id"].ToString();
                }

                if (request.Headers["x-wps-weboffice-token"] != null)
                {
                    token = request.Headers["x-wps-weboffice-token"].ToString();
                }
                if (request["_w_userid"] != null)
                {
                    userId = request["_w_userid"].ToString();
                    LogHelper.Info("userid：" + userId);
                }
                WPSUserInfo userModel = LoginUtils.GetUserInfo(token);
                if (userModel == null && !string.IsNullOrEmpty(userId))
                {
                    using (WPSModel context = new WPSModel())
                    {
                        userModel = context.WPSUserInfo.Where(u => u.ID == userId).FirstOrDefault();
                    }
                }
                if (userModel == null)
                {
                    return null;
                }
                WPSFileInfo fileModel = new WPSFileInfo();
                if (request.Files.Count > 0)
                {
                    HttpPostedFileBase file = request.Files[0];
                    using (WPSModel context = new WPSModel())
                    {
                        fileModel.ID = Guid.NewGuid().ToString();
                        fileModel.NAME = file.FileName;
                        fileModel.SIZE = file.ContentLength;
                        fileModel.VERSION = 1;
                        fileModel.CREATOR = userModel.ID;
                        fileModel.CREATE_DATE = DateTime.Now;
                        fileModel.DOWNLOAD_URL = WPSConfig.Download_Host + "/weboffice/getFile?fileId=" + fileModel.ID;
                        string filePath = HttpContext.Current.Server.MapPath("~/") + "Files\\" + fileModel.ID + "." + WPSFileUtils.GetFileExt(fileModel.NAME);
                        LogHelper.Info("filePath：" + filePath);
                        file.SaveAs(filePath);
                        LogHelper.Info("download_url：" + fileModel.DOWNLOAD_URL);
                        context.WPSFileInfo.Add(fileModel);
                        context.SaveChanges();
                    }
                }
              
                string param = "_w_appid=" + WPSConfig.AppId + "&_w_fid=" + fileModel.ID +"&"+ ApiUtils.Token + "=" + token + "&_w_userid=" + userModel.ID +"&_w_permission=write";
                String signature = WpsUtils.getSignature(WpsUtils.paramToMap(param), WPSConfig.AppKey);
                string url = WPSConfig.Domain + "/office/w/" + fileModel.ID + "?";
                url += param + "&_w_signature=" + signature;
                obj["redirect_url"] = url;
                obj["user_id"] = userModel.ID;
                LogHelper.Info("redirect_url：" + url);
                LogHelper.Info("离开v1/3rd/file/new");
                return Json(obj);
            }
            catch (Exception e)
            {
                LogHelper.Error(e.Message);
            }
            return null;
        }
        #endregion

        #region 上传文件新版本
        /// <summary>
        /// 上传文件新版本
        /// </summary>
        /// <returns></returns>
        [HttpPost, Route("v1/3rd/file/save")]
        public JsonResult<JObject> SaveFile()
        {
            LogHelper.Info("进入v1/3rd/file/save");
            try
            {
                string userid = string.Empty;
                WPSFileInfo fileModel = new WPSFileInfo();
                JObject jsonObject = new JObject();

                HttpContextBase httpContextBase = (HttpContextBase)Request.Properties["MS_HttpContext"];
                if (httpContextBase == null)
                {
                    return null;
                }
                HttpRequestBase request = httpContextBase.Request;
                string fileId = string.Empty;
                string token = string.Empty;
                string ext = string.Empty;
                if (request.Headers["x-weboffice-file-id"] != null)
                {
                    fileId = request.Headers["x-weboffice-file-id"].ToString();
                }
                if (request.Headers["x-wps-weboffice-token"] != null)
                {
                    token = request.Headers["x-wps-weboffice-token"].ToString();
                }
                if (request["_w_userid"] != null)
                {
                    userid = request["_w_userid"].ToString();
                    LogHelper.Info("userid：" + userid);
                }
                LogHelper.Info("fileId：" + fileId + ";<br/>token=" + token + ";<br/>userid=" + userid);
                WPSUserInfo userInfo = CacheUtils.Get<WPSUserInfo>(token);
                if (userInfo == null && !string.IsNullOrEmpty(userid))
                {
                    using (WPSModel context = new WPSModel())
                    {
                        userInfo = context.WPSUserInfo.Where(u => u.ID == userid).FirstOrDefault();
                    }
                }
                if (userInfo == null)
                {
                    return null;
                }
                LogHelper.Info("HttpContext.Current.Server.MapPath：" + HttpContext.Current.Server.MapPath("~/"));

                if (request.Files.Count > 0)
                {
                    HttpPostedFileBase file = request.Files[0];
                    using (WPSModel context = new WPSModel())
                    {
                        fileModel = context.WPSFileInfo.Where(f => f.ID == fileId).FirstOrDefault();
                        if (fileModel == null)
                        {
                            return null;
                        }
                        ext = WPSFileUtils.GetFileExt(fileModel.NAME);
                        fileModel.SIZE = file.ContentLength;
                        fileModel.VERSION = fileModel.VERSION + 1;
                        fileModel.DOWNLOAD_URL = WPSConfig.Download_Host + "/weboffice/getFile?fileId=" + fileModel.ID + "&version=" + fileModel.VERSION;
                        fileModel.EDITOR = userInfo.ID;
                        fileModel.EDIT_DATE = DateTime.Now;

                        FileHistoryVersion fileHistory = new FileHistoryVersion();
                        fileHistory.ID = Guid.NewGuid().ToString();
                        fileHistory.FILE_ID = fileModel.ID;
                        fileHistory.SIZE = fileModel.SIZE;
                        fileHistory.FILE_NAME = fileModel.NAME;
                        fileHistory.CREATOR = fileModel.CREATOR;
                        fileHistory.CREATE_DATE = DateTime.Now;
                        fileHistory.EDITOR = userInfo.ID;
                        fileHistory.EDIT_DATE = DateTime.Now;
                        fileHistory.VERSION = fileModel.VERSION;
                        fileHistory.DOWNLOAD_URL = fileModel.DOWNLOAD_URL;
                        context.FileHistoryVersion.Add(fileHistory);
                        context.SaveChanges();
                        LogHelper.Info("download_url：" + fileModel.DOWNLOAD_URL);
                        JObject fileObject = new JObject();
                        fileObject["id"] = fileModel.ID;
                        fileObject["name"] = fileModel.NAME;
                        fileObject["version"] = fileModel.VERSION;
                        fileObject["size"] = fileModel.SIZE;
                        fileObject["download_url"] = fileModel.DOWNLOAD_URL;
                        jsonObject["file"] = fileObject;
                    }
                    if (fileModel != null)
                    {
                        string filePath = HttpContext.Current.Server.MapPath("~/") + "Files\\" + fileModel.ID + "_v" + fileModel.VERSION.ToString() + "." + ext;
                        LogHelper.Info("filePath：" + filePath);
                        file.SaveAs(filePath);
                    }
                    else
                    {
                        LogHelper.Info("fileModel is null");
                    }
                }
                return Json(jsonObject);
            }
            catch (Exception ex)
            {
                LogHelper.Error("v1/3rd/file/save：" + ex.Message);
            }
            LogHelper.Info("离开v1/3rd/file/save");
            return null;
        }
        #endregion

        #region 获取获取所有历史版本文件信息
        /// <summary>
        /// 获取获取所有历史版本文件信息
        /// </summary>
        /// <returns></returns>
        [HttpPost, Route("v1/3rd/file/history")]
        public JsonResult<JObject> GetHistory()
        {
            try
            {
                LogHelper.Info("进入v1/3rd/file/history");
                string fileId = string.Empty;
                string token = string.Empty;
                string userId = string.Empty;
                HttpContextBase httpContextBase = (HttpContextBase)Request.Properties["MS_HttpContext"];
                if (httpContextBase == null)
                {
                    return null;
                }
                HttpRequestBase request = httpContextBase.Request;
                if (request.Headers["x-weboffice-file-id"] != null)
                {
                    fileId = request.Headers["x-weboffice-file-id"].ToString();
                }
                if (request.Headers["x-wps-weboffice-token"] != null)
                {
                    token = request.Headers["x-wps-weboffice-token"].ToString();
                }
                if (request["_w_userid"] != null)
                {
                    userId = request["_w_userid"].ToString();
                    LogHelper.Info("userid：" + userId);
                }
                JObject result = new JObject();
                JArray jarray = new JArray();

                WPSUserInfo userInfo = CacheUtils.Get<WPSUserInfo>(token);
                if (userInfo == null && !string.IsNullOrEmpty(userId))
                {
                    using (WPSModel context = new WPSModel())
                    {
                        userInfo = context.WPSUserInfo.Where(u => u.ID == userId).FirstOrDefault();
                    }
                }
                if (userInfo == null)
                {
                    return null;
                }
                using (WPSModel context = new WPSModel())
                {
                    IEnumerable<FileHistoryVersion> history = context.FileHistoryVersion.Where(f => f.FILE_ID == fileId);
                    if (history != null && history.Any())
                    {
                        DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
                        foreach (FileHistoryVersion item in history)
                        {
                            JObject itemObject = new JObject();
                            itemObject.Add("id", item.FILE_ID);
                            itemObject.Add("name", item.FILE_NAME);
                            itemObject.Add("version", item.VERSION);
                            itemObject.Add("size", item.SIZE);
                            itemObject.Add("download_url", item.DOWNLOAD_URL);
                            if (item.CREATE_DATE != null)
                            {
                                long createTimeStamp = (long)(Convert.ToDateTime(item.CREATE_DATE) - startTime).TotalMilliseconds / 1000;
                                itemObject.Add("create_time", createTimeStamp);
                            }
                            if (item.EDIT_DATE != null)
                            {
                                long editTimeStamp = (long)(Convert.ToDateTime(item.EDIT_DATE) - startTime).TotalMilliseconds / 1000;
                                itemObject.Add("modify_time", editTimeStamp);
                            }
                            JObject creator = new JObject();
                            creator.Add("id", userInfo.ID);
                            creator.Add("name", userInfo.NAME);
                            creator.Add("avatar_url", userInfo.AVATAR_URL);
                            itemObject.Add("creator", creator);

                            creator = new JObject();
                            creator.Add("id", userInfo.ID);
                            creator.Add("name", userInfo.NAME);
                            creator.Add("avatar_url", userInfo.AVATAR_URL);
                            itemObject.Add("modifier", creator);

                            jarray.Add(itemObject);
                        }
                    }
                    result.Add("histories", jarray);
                }
                LogHelper.Info(result.ToString());
                LogHelper.Info("离开v1/3rd/file/history");
                return Json(result);
            }
            catch (Exception e)
            {
                LogHelper.Error("v1/3rd/file/history" + e.Message);
            }
            return null;
        }
        #endregion

        #region 文件重命名
        /// <summary>
        /// 文件重命名
        /// </summary>
        /// <returns></returns>
        [HttpPut, Route("v1/3rd/file/rename")]
        public JsonResult<JObject> Rename()
        {
            LogHelper.Info("进入v1/3rd/file/rename");
            try
            {
                string newName = string.Empty;
                string fileId = string.Empty;
                WPSFileInfo fileModel = null;
                HttpContextBase httpContextBase = (HttpContextBase)Request.Properties["MS_HttpContext"];
                if (httpContextBase == null)
                {
                    return null;
                }
                HttpRequestBase request = httpContextBase.Request;
                if (request.Headers["x-weboffice-file-id"] != null)
                {
                    fileId = request.Headers["x-weboffice-file-id"].ToString(); 
                }
                if (request["name"] != null)
                {
                    newName = request["name"].ToString();
                }
                if (request.InputStream.Length>0)
                {
                    string nameJson = string.Empty;
                    LogHelper.Info("request.InputStream 有数据 ");
                    byte[] byteArray = new byte[request.InputStream.Length];
                    System.IO.Stream stream = request.InputStream;
                    stream.Read(byteArray, 0, byteArray.Length);
                    nameJson = System.Text.Encoding.UTF8.GetString(byteArray);
                    JObject json = JsonConvert.DeserializeObject<JObject>(nameJson);
                    newName = json["name"].ToString();
                }
                LogHelper.Info("fileId："+ fileId+ ";newName："+ newName);
                if (fileId != null)
                {
                    using (WPSModel context = new WPSModel())
                    {
                        fileModel = context.WPSFileInfo.Where(f => f.ID == fileId).FirstOrDefault();
                        fileModel.NAME = newName;
                        context.SaveChanges();
                    }
                }
                JObject obj = new JObject();
                obj["code"] = "200";
                obj["msg"] = "";
                obj["data"] = "";
                LogHelper.Info("离开v1/3rd/file/rename");
                return Json(obj);
            }
            catch (Exception ex)
            {
                LogHelper.Error("v1/3rd/file/rename：" + ex.Message + "<br/>" + ex.StackTrace);
            }
            return null;
        }
        #endregion

        #region 获取特定版本的文件信息 
        /// <summary>
        /// 获取特定版本的文件信息 
        /// </summary>
        /// <returns></returns>
        [HttpGet, Route("v1/3rd/file/version/{version}")]
        public JsonResult<JObject> Version(long version)
        {
            LogHelper.Info("进入v1/3rd/file/version");
            try
            {
                JObject jsonObject = new JObject();
                JObject file = new JObject();
                string fileId = string.Empty;
                string token = string.Empty;
                string userId = string.Empty;
                try
                {
                    HttpContextBase httpContextBase = (HttpContextBase)Request.Properties["MS_HttpContext"];
                    if (httpContextBase == null)
                    {
                        return null;
                    }
                    HttpRequestBase request = httpContextBase.Request;
                    if (request.Headers["x-weboffice-file-id"] != null)
                    {
                        fileId = request.Headers["x-weboffice-file-id"].ToString();
                        LogHelper.Info("x-weboffice-file-id：" + fileId);
                    }
                    if (request.Headers["x-wps-weboffice-token"] != null)
                    {
                        token = request.Headers["x-wps-weboffice-token"].ToString();
                        LogHelper.Info("x-wps-weboffice-token：" + token);
                    }
                    if (request["_w_userid"] != null)
                    {
                        userId = request["_w_userid"].ToString();
                        LogHelper.Info("userid：" + userId);
                    }
                    if (request["version"] != null)
                    {
                        version = Convert.ToInt64(request["version"].ToString());

                    }
                    WPSUserInfo userInfo = CacheUtils.Get<WPSUserInfo>(token);
                    FileHistoryVersion fileHistory = null;
                    if (userInfo == null && !string.IsNullOrEmpty(userId))
                    {
                        using (WPSModel context = new WPSModel())
                        {
                            userInfo = context.WPSUserInfo.Where(u => u.ID == userId).FirstOrDefault();
                        }
                    }
                    LogHelper.Info("version：" + version.ToString());
                    LogHelper.Info("fileId：" + fileId);
                    using (WPSModel context = new WPSModel())
                    {
                        DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
                        fileHistory = context.FileHistoryVersion.Where(f => f.FILE_ID == fileId && f.VERSION == version).FirstOrDefault();
                        if (fileHistory == null)
                        {
                            LogHelper.Info("fileHistory is null  " );
                        }
                        file.Add("id", fileHistory.ID);
                        file.Add("name", fileHistory.FILE_NAME);
                        file.Add("version", fileHistory.VERSION);
                        if (fileHistory.CREATE_DATE != null)
                        {
                            long createTimeStamp = (long)(Convert.ToDateTime(fileHistory.CREATE_DATE) - startTime).TotalMilliseconds / 1000;
                            file.Add("create_time", createTimeStamp);
                        }
                        file.Add("creator", fileHistory.CREATOR);
                        file.Add("modifier", fileHistory.EDITOR);
                        if (fileHistory.EDIT_DATE != null)
                        {
                            long modifierStamp = (long)(Convert.ToDateTime(fileHistory.EDIT_DATE) - startTime).TotalMilliseconds / 1000;
                            file.Add("modify_time", modifierStamp);
                        }
                        file.Add("download_url", fileHistory.DOWNLOAD_URL);
                        jsonObject.Add("file", file);
                    }
                }
                catch (Exception e)
                {
                    throw new Exception("v1/3rd/file/version" + e.Message + "<br>" + e.StackTrace);
                }
                LogHelper.Info("离开v1/3rd/file/version");
                return Json(jsonObject);
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex.Message);
            }
            return null;
        }
        #endregion

        #region 通知此文件目前有那些人正在协作（TODO）
        /// <summary>
        /// 通知此文件目前有那些人正在协作（TODO）
        /// </summary>
        [HttpPost, Route("v1/3rd/file/online")]
        public void Online()
        {
            LogHelper.Info("进入v1/3rd/file/online");
            LogHelper.Info("离开v1/3rd/file/online");
        }
        #endregion

        #region 回调通知（TODO）
        /// <summary>
        /// 回调通知（TODO）
        /// </summary>
        [HttpPost, Route("v1/3rd/onnotify")]
        public void OnNotify()
        {
            LogHelper.Info("进入v1/3rd/onnotify");
            LogHelper.Info("离开v1/3rd/onnotify");
        }
        #endregion
    }
}
